use log::LevelFilter;

#[derive(Debug)]
struct RawArgs {
    ip: Option<String>,
    port: Option<u16>,
    db_path: Option<String>,
    log_level: Option<String>,
}

fn parse_raw_args() -> RawArgs {
    let mut ip: Option<String> = None;
    let mut port: Option<u16> = None;
    let mut db_path: Option<String> = None;
    let mut log_level: Option<String> = None;

    let mut iter = std::env::args().skip(1).peekable();
    while let Some(arg) = iter.next() {
        if let Some(v) = arg.strip_prefix("--ip=") {
            ip = Some(v.to_string());
            continue;
        }
        if arg == "--ip" {
            if let Some(v) = iter.peek() {
                if !v.starts_with("--") {
                    ip = Some(iter.next().unwrap());
                    continue;
                }
            }
        }

        if let Some(v) = arg.strip_prefix("--port=") {
            port = v.parse().ok();
            continue;
        }
        if arg == "--port" {
            if let Some(v) = iter.peek() {
                if !v.starts_with("--") {
                    port = iter.next().and_then(|s| s.parse().ok());
                    continue;
                }
            }
        }

        if let Some(v) = arg.strip_prefix("--db-path=") {
            db_path = Some(v.to_string());
            continue;
        }
        if arg == "--db-path" {
            if let Some(v) = iter.peek() {
                if !v.starts_with("--") {
                    db_path = Some(iter.next().unwrap());
                    continue;
                }
            }
        }

        if let Some(v) = arg.strip_prefix("--log-level=") {
            log_level = Some(v.to_string());
            continue;
        }
        if arg == "--log-level" {
            if let Some(v) = iter.peek() {
                if !v.starts_with("--") {
                    log_level = Some(iter.next().unwrap());
                    continue;
                }
            }
        }
    }

    RawArgs { ip, port, db_path, log_level }
}

#[derive(Debug, Clone)]
pub struct Config {
    pub ip: String,
    pub port: u16,
    pub db_path: String,
    pub log_level: LevelFilter,
}

impl Config {
    pub fn from_args_and_env() -> Self {
        let args = parse_raw_args();
        
        // 优先级：命令行参数 > 环境变量 > 默认值
        let ip = args.ip
            .or_else(|| std::env::var("ROCKSDBREST_IP").ok())
            .unwrap_or_else(|| "0.0.0.0".to_string());
            
        let port = args.port
            .or_else(|| std::env::var("ROCKSDBREST_PORT").ok().and_then(|s| s.parse().ok()))
            .unwrap_or(3030);
            
        let db_path = args.db_path
            .or_else(|| std::env::var("ROCKSDBREST_DB_PATH").ok())
            .unwrap_or_else(|| "data".to_string());

        let db_path = std::fs::canonicalize(&db_path)
            .unwrap_or_else(|_| std::path::PathBuf::from(db_path))
            .to_string_lossy()
            .into_owned();
            
        // 解析日志级别
        let log_level = args.log_level
            .or_else(|| std::env::var("ROCKSDBREST_LOG_LEVEL").ok())
            .map(|level| match level.to_lowercase().as_str() {
                "trace" => LevelFilter::Trace,
                "debug" => LevelFilter::Debug,
                "info" => LevelFilter::Info,
                "warn" => LevelFilter::Warn,
                "error" => LevelFilter::Error,
                _ => LevelFilter::Info,
            })
            .unwrap_or(LevelFilter::Info);
        
        Self { ip, port, db_path, log_level }
    }
}